package com.rednote.common.aspect;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Arrays;

@Component
@Aspect
@Slf4j
public class LogAspect {

    private final ObjectMapper objectMapper;

    public LogAspect(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Pointcut("execution(* com.rednote.controller..*.*(..))")
    public void controllerPoint() {}

    @Around("controllerPoint()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = null;
        if (attributes != null) {
            request = attributes.getRequest();
        }

        String url = null;
        if (request != null) {
            url = request.getRequestURL().toString();
        }
        String method = null;
        if (request != null) {
            method = request.getMethod();
        }
        String ip = null;
        if (request != null) {
            ip = request.getRemoteAddr();
        }
        String className = point.getSignature().getDeclaringTypeName();
        String methodName = point.getSignature().getName();
        String params = Arrays.toString(point.getArgs());

        log.info("请求开始, URL: {}, Method: {}, IP: {}, Class: {}, Method: {}, Params: {}",
                url, method, ip, className, methodName, params);

        Object result = point.proceed();

        long duration = System.currentTimeMillis() - beginTime;
        log.info("请求结束, 耗时: {}ms, 返回值: {}", duration, objectMapper.writeValueAsString(result));

        return result;
    }
}
